home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / Snippets / Devices / SCSI Simple Sample / Src / DoListSCSIDevices.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-24  |  4.9 KB  |  132 lines  |  [TEXT/KAHL]

  1. /*                                DoListSCSIDevices.c                                */
  2. /*
  3.  * DoListSCSIDevices.c
  4.  * Copyright © 1992-94 Apple Computer Inc. All Rights Reserved.
  5.  *
  6.  * Find all SCSI devices. The alogrithm first asks the SCSI Manager for the
  7.  * number of busses, then loops through each bus for each device and LUN.
  8.  * old SCSI Manager.
  9.  */
  10. #include "SCSISimpleSample.h"
  11. /*
  12.  * Note: if you are running on a Quadra 840-AV with a CD300, this will hang the
  13.  * Macintosh if it tries to access LUN 1 when calling the asynchronous SCSI
  14.  * Manager. You have to enable > 0 logical units in the Test Menu. This bug was
  15.  * fixed in the SCSI Manager Extension (4.3f1) and in the PowerPC ROMs.
  16.  */
  17.  
  18. void
  19. DoListSCSIDevices(void)
  20. {
  21.         OSErr                            status;
  22.         unsigned short                    lastHostBus;
  23.         unsigned short                    initiatorID;
  24.         unsigned short                    bus;
  25.         unsigned short                    targetID;
  26.         unsigned short                    LUN;
  27.         DeviceIdent                        scsiDevice;
  28.         SCSIGetVirtualIDInfoPB            scsiGetVirtualIDInfo;
  29.         short                            deviceCount;
  30.         Str255                            work;
  31.         
  32.         LOG("\pList all SCSI Devices");
  33.         deviceCount = 0;
  34.         /*
  35.          * If we have the asynchronous SCSI Manager, find out how many busses
  36.          * are present on this system. If not, force a "single bus" scan, since 
  37.          * DoSCSICommandWithSense ignores the hostBus information if it is
  38.          * forced into "old-style" calls.
  39.          */
  40.         if (gEnableNewSCSIManager)
  41.             status = SCSIGetHighHostBusAdaptor(&lastHostBus);
  42.         else {
  43.             status = noErr;
  44.             lastHostBus = 0;                /* Force one bus only            */
  45.         }
  46.         if (status == noErr) {
  47.             for (bus = 0; bus <= lastHostBus; bus++) {
  48.                 /*
  49.                  * Look at this SCSI bus. This would be a good place to allocate
  50.                  * the SCSIExecIO command block. In this sample, however, it's
  51.                  * allocated on each call to AsyncSCSI which is inefficient.
  52.                  * Note that it is possible to have busses with no devices.
  53.                  * For example, if a system has a built-in internal and external
  54.                  * SCSI Bus (such as the Quadra 950 or PowerMac 8100), a third-
  55.                  * party bus adaptor that supports the asynchronous SCSI Manager
  56.                  * would be assigned bus 2 (with busses 0 and 1 referencing the
  57.                  * internal system busses). In this case, a system could have
  58.                  * no devices on bus 0 or 1.
  59.                  */
  60.                 *((long *) &scsiDevice) = 0;
  61.                 scsiDevice.bus = bus;
  62.                 status = SCSIGetInitiatorID(scsiDevice, &initiatorID);
  63.                 if (status != noErr)
  64.                     continue;
  65.                 /*
  66.                  * SCSIGetInitiatorID returned the bus ID of the Macintosh.
  67.                  * This is almost always seven, but only the SCSI Manager
  68.                  * knows for sure. Note that, by getting the Macintosh
  69.                  * bus ID dynamically, we prepare the code for a future
  70.                  * system that permitted more than one Macintosh on the
  71.                  * same SCSI bus.
  72.                  */
  73.                 for (targetID = 0; targetID <= 7; targetID++) {
  74.                     if (targetID == initiatorID)
  75.                         continue;
  76.                     scsiDevice.targetID = targetID;
  77.                     for (LUN = 0; LUN <= gMaxLogicalUnit; LUN++) {
  78.                         /*
  79.                          * Try to send a command to this LUN. If it fails, don't
  80.                          * try for higher-valued LUNs. SCSICheckForDevicePresent
  81.                          * looks, carefully, at the returned error to distinguish
  82.                          * between missing devices and devices that are present,
  83.                          * but unable to respond, such as CD-ROM players with
  84.                          * no disk inserted. This call to SCSICheckForDevicePresent
  85.                          * will use the asynchronous SCSI Manager if it can.
  86.                          */
  87.                         scsiDevice.LUN = LUN;
  88.                         if (SCSICheckForDevicePresent(scsiDevice, TRUE) == FALSE)
  89.                             break;                        /* Don't look for LUNs    */
  90.                         else {
  91.                             ++deviceCount;                /* Found a device        */
  92.                             DoGetDriveInfo(scsiDevice, TRUE);    /* no intro msg    */
  93.                         }                                /* Check status            */
  94.                     }                                    /* LUN loop                */
  95.                 }                                        /* Target loop            */
  96.             }                                            /* Bus loop                */
  97.             /*
  98.              * Now, we need to look at the hard-wired SCSI drive addresses and
  99.              * check whether a third-party hardware interface that does not use
  100.              * the asynchronous SCSI Manager recognizes this address.
  101.              */
  102.             scsiDevice.bus = 0;
  103.             for (targetID = 0; targetID <= 6; targetID++) {
  104.                  CLEAR(scsiGetVirtualIDInfo);
  105.                  scsiGetVirtualIDInfo.scsiPBLength = sizeof scsiGetVirtualIDInfo;
  106.                  scsiGetVirtualIDInfo.scsiOldCallID = targetID;
  107.                  status = SCSIAction((SCSI_PB *) &scsiGetVirtualIDInfo);
  108.                  if (status != noErr) {
  109.                      /*
  110.                       * The asynchronous SCSI Manager does not know about this
  111.                       * target ID. Check whether it exists (forcing the request
  112.                       * to use the original SCSI Manager).
  113.                       */
  114.                      scsiDevice.targetID = targetID;
  115.                      for (LUN = 0; LUN <= gMaxLogicalUnit; LUN++) {
  116.                          scsiDevice.LUN = LUN;
  117.                         if (SCSICheckForDevicePresent(scsiDevice, FALSE) == FALSE)
  118.                             break;                        /* Don't look for LUNs    */
  119.                         else {
  120.                             ++deviceCount;                /* Found a device        */
  121.                             DoGetDriveInfo(scsiDevice, TRUE);    /* no intro msg    */
  122.                         }                                /* Check status            */
  123.                     }
  124.                 }
  125.             }
  126.         }                                                /* Found a host adaptor    */
  127.         NumToString(deviceCount, work);
  128.         AppendPascalString(work, "\p SCSI Devices");
  129.         LOG(work);
  130. }        
  131.  
  132.